package com.alks.function.service.impl.web.pay;

import com.alks.common.aop.AutoPageAop;
import com.alks.common.data.thread.UserIdThread;
import com.alks.common.service.RedisService;
import com.alks.common.utils.DateUtils;
import com.alks.common.utils.excelUtils.BizAssertUtils;
import com.alks.common.utils.excelUtils.ExcelUtils;
import com.alks.common.utils.stringUtils.ZStringUtils;
import com.alks.entity.data.entity.ExportPlanInfo;
import com.alks.entity.data.entity.SdCompany;
import com.alks.entity.data.entity.webPay.FinancePayable;
import com.alks.entity.data.entity.webPay.FinanceReceivable;
import com.alks.entity.data.response.ResponseInfo;
import com.alks.entity.exception.ServiceErrorException;
import com.alks.function.mapper.web.pay.PcPayMapper;
import com.alks.function.service.web.pay.PcPayService;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.support.atomic.RedisAtomicInteger;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestBody;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author:hxl
 * @create: 2024-11-22 10:24
 * @Description:
 */
@Slf4j
@Service
public class PcPayServiceImpl implements PcPayService {
    @Autowired
    PcPayMapper pcPayMapper;

    @Override
    @AutoPageAop
    public ResponseInfo receivableList(@RequestBody FinanceReceivable req) {
        Map<String, Object> map = new HashMap<>();
        if (req.getActAmt() == null) req.setActAmt(Double.valueOf(2.0D));
        req.setCompanyId(UserIdThread.get().getCompanyId());
        List<FinanceReceivable> list = pcPayMapper.receivableList(req);
        Map<String, Object> result = pcPayMapper.sumStorage1(req);
        Map<String, Object> result2 = pcPayMapper.sumStorage2(req);
        result.put("outPair", result2.get("outPair"));
        result.put("outAmt", result2.get("outAmt"));
        map.put("list", list);
        map.put("result", result);
        map.put("total", new PageInfo<>(list).getTotal());
        return ResponseInfo.ok(map);
    }

    @Override
    public ResponseInfo selectArDetailList(FinanceReceivable req) {
        List<FinanceReceivable> list = pcPayMapper.selectArDetailList(req);
        return ResponseInfo.ok(list);
    }

    @Override
    public ResponseInfo addDetail(List<FinanceReceivable> req) {
        extracted(req);
        Integer count = pcPayMapper.addDetail(req);
        return ResponseInfo.ok();
    }

    @Override
    public ResponseInfo deleteDetail(FinanceReceivable req) {
        Integer count = pcPayMapper.deleteDetail(req);
        return ResponseInfo.ok();
    }

    @Override
    @AutoPageAop
    public ResponseInfo infoList(ExportPlanInfo exportPlanInfo) {
        List<ExportPlanInfo> list = pcPayMapper.infoList(exportPlanInfo);
        return ResponseInfo.ok(list);
    }

    @Override
    public ResponseInfo cfm(String receiptNo, String cfmFlag) {
        FinanceReceivable param = new FinanceReceivable();
        param.setReceiptNo(receiptNo);
        param.setCompanyId(UserIdThread.get().getCompanyId());
        param.setCfmFlag(cfmFlag);
        param.setCfmUser((String) UserIdThread.get().getUserName());
        param.setCfmTime((Date) new Date());
        if ("Y".equals(cfmFlag)) {
            param.setCfmTime(new Date());
            param.setCfmUser(UserIdThread.get().getLoginName());
        }
        Integer count = pcPayMapper.cfm(param);
        return ResponseInfo.ok();
    }

    @Override
    public ResponseInfo updateRemark(String receiptNo, String remark) {
        FinanceReceivable param = new FinanceReceivable();
        param.setReceiptNo(receiptNo);
        param.setCompanyId(UserIdThread.get().getCompanyId());
        param.setRemark(remark);
        return ResponseInfo.ok(pcPayMapper.updateRemark(param));
    }

    @Override
    public ResponseInfo tempDetailList(FinanceReceivable req) {
        if (ZStringUtils.isEmpty(req.getCompanyId())) req.setCompanyId(UserIdThread.get().getCompanyId());
        return ResponseInfo.ok(pcPayMapper.tempDetailList(req));
    }

    @Override
    public ResponseInfo addTempDetail(List<FinanceReceivable> req) {
        extracted(req);
        Integer count = pcPayMapper.addTempDetail(req);
        return ResponseInfo.ok();
    }

    @Override
    public ResponseInfo selectTempDeleteList(FinanceReceivable req) {
        return ResponseInfo.ok(pcPayMapper.selectTempDeleteList(req));
    }

    @Override
    public int deleteTempByReceiptNo(FinanceReceivable req) {
        return pcPayMapper.deleteTempByReceiptNo(req);
    }

    @Override
    public SdCompany getCompanyById(String hf) {
        return pcPayMapper.getCompanyById(hf);
    }

    @Override
    public List<FinanceReceivable> selectPrintDataByPayNo(FinanceReceivable financeReceivable) {
        return pcPayMapper.selectPrintDataByPayNo(financeReceivable);
    }

    @Override
    @AutoPageAop
    public ResponseInfo receivableAoaList(FinancePayable financePayable) {
        if (financePayable.getActAmt() == null) {
            financePayable.setActAmt(Double.valueOf(2.0D));
        }
        financePayable.setOrderType("大货");
        financePayable.setCompanyId(UserIdThread.get().getCompanyId());
        Map<String, Object> map = new HashMap<>();
        List<FinancePayable> list = pcPayMapper.payableAoaList(financePayable);
        Map<String, Object> summaryRoot = pcPayMapper.sumAoaStorage(financePayable);
        map.put("list", list);
        map.put("summaryRoot", summaryRoot);
        map.put("total", new PageInfo<>(list).getTotal());
        return ResponseInfo.ok(map);
    }

    @Override
    public ResponseInfo updateAoaDate(String aoaDate, List<FinancePayable> records) {
        Date date;
        BizAssertUtils.notEmpty(records, "未选择任何记录!");
        if (aoaDate.length() != 7) {
            return ResponseInfo.error("无效的日期信息");
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
        try {
            date = sdf.parse(aoaDate);
        } catch (ParseException e) {
            return ResponseInfo.error("月份解析错误");
        }
        List<FinancePayable> insertList = new ArrayList();
        Iterator var4 = records.iterator();

        while (var4.hasNext()) {
            FinancePayable item = (FinancePayable) var4.next();
            item.setAoaDate(date);
            int num = pcPayMapper.selectReconcilitaionNum(item);
            if (num == 0) {
                insertList.add(item);
            }
        }
        if (insertList.size() > 0) {
            pcPayMapper.addReconcilitaion(insertList);
        }
        int i = pcPayMapper.updateAoaDate(records);
        return ResponseInfo.ok(i);
    }

    @Override
    public ResponseInfo updateAoaCfmN(List<FinancePayable> records) {
        Iterator var2 = records.iterator();

        while (var2.hasNext()) {
            FinancePayable item = (FinancePayable) var2.next();
            int num = pcPayMapper.selectCfmNum(item);
            if (num > 0) {
                throw new ServiceErrorException("存在结算明细数据,不能取消核检!!!");
            }

            item.setAoaCfmDate(new Date());
            item.setAoaCfm("N");
            item.setAoaCfmUser(UserIdThread.get().getLoginName());
            item.setAoaDate(null);
        }
        return ResponseInfo.ok(pcPayMapper.updateAoaCfm(records));
    }

    @Override
    public ResponseInfo updateAoaCfmY(List<FinancePayable> records) {
        Iterator var2 = records.iterator();

        FinancePayable item;
        do {
            if (!var2.hasNext()) {
                return ResponseInfo.ok(pcPayMapper.updateAoaCfm(records));
            }
            item = (FinancePayable) var2.next();
            item.setAoaCfmDate(new Date());
            item.setAoaCfm("Y");
            item.setAoaCfmUser(UserIdThread.get().getLoginName());
        } while (item.getAoaDate() != null);

        throw new ServiceErrorException("发票号[" + item.getInvoiceNo() + "]不存在对账年月数据,不能对账审核!!");
    }

    @Override
    @AutoPageAop
    public ResponseInfo payableList(FinancePayable financePayable) {
        if (financePayable.getActAmt() == null) {
            financePayable.setActAmt(Double.valueOf(2.0D));
        }
        Map<String, Object> map = new HashMap<>();
        financePayable.setCompanyId(UserIdThread.get().getCompanyId());
        List<FinancePayable> list = pcPayMapper.payableList(financePayable);
        Map<String, Object> summaryRoot = pcPayMapper.sumStorage(financePayable);
        map.put("summaryRoot", summaryRoot);
        map.put("list", list);
        map.put("total", new PageInfo<>(list).getTotal());
        return ResponseInfo.ok(map);
    }

    @Override
    public ResponseInfo payableDetailList(FinancePayable financePayable) {
        return ResponseInfo.ok(pcPayMapper.payableDetailList(financePayable));
    }

    @Autowired
    RedisService redisService;

    @Override
    public ResponseInfo addDetail1(List<FinancePayable> financePayable) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMM");
        String date = sdf.format(new Date());
        Iterator var4 = financePayable.iterator();
        String key = "S" + date;
        RedisAtomicInteger ato = new RedisAtomicInteger(key, redisService.getConnectionFactory());
        int i = ato.incrementAndGet();
        while (var4.hasNext()) {
            FinancePayable item = (FinancePayable) var4.next();
            item.setPayNo("F" + date + String.format("%04d",i));
            item.setSysUser(UserIdThread.get().getLoginName());
            item.setSysDate(new Date());
        }
        pcPayMapper.addDetail1(financePayable);
        return ResponseInfo.ok();
    }

    @Override
    public ResponseInfo deleteDetail1(FinancePayable financePayable) {
        int i = pcPayMapper.deleteDetail1(financePayable);
        return ResponseInfo.ok(i);
    }

    @Override
    public ResponseInfo updateCfmFlag(String payNo, String cfmFlag) {
        FinancePayable param = new FinancePayable();
        param.setPayNo(payNo);
        param.setCompanyId(UserIdThread.get().getCompanyId());
        param.setCfmFlag(cfmFlag);
        param.setCfmUser((String) null);
        param.setCfmTime((Date) null);
        if ("Y".equals(cfmFlag)) {
            param.setCfmTime(new Date());
            param.setCfmUser(UserIdThread.get().getLoginName());
        }
        return ResponseInfo.ok(pcPayMapper.updateCfmFlag(param));
    }

    @Override
    public ResponseInfo updateRemark1(String payNo, String remark) {
        FinancePayable param = new FinancePayable();
        param.setPayNo(payNo);
        param.setCompanyId(UserIdThread.get().getCompanyId());
        param.setRemark(remark);
        return ResponseInfo.ok(pcPayMapper.updateRemark1(param));
    }

    @Override
    public ResponseInfo updateAoaQtyY(List<FinancePayable> records) {
        List<FinancePayable> insertList = new ArrayList();
        Iterator var3 = records.iterator();

        while (var3.hasNext()) {
            FinancePayable item = (FinancePayable) var3.next();
            item.setAoaQty("Y");
            int num = pcPayMapper.selectReconcilitaionNum(item);
            if (num == 0) {
                insertList.add(item);
            }
        }

        if (insertList.size() > 0) {
            System.out.println("---insertCount----");
            this.pcPayMapper.addReconcilitaion(insertList);
        }

        return ResponseInfo.ok(this.pcPayMapper.updateAoaQty(records));

    }

    @Override
    public ResponseInfo updateAoaQtyN(List<FinancePayable> records) {
        Iterator var2 = records.iterator();

        while (var2.hasNext()) {
            FinancePayable item = (FinancePayable) var2.next();
            int num = pcPayMapper.selectCfmNum(item);
            if (num > 0) {
                throw new ServiceErrorException("存在结算明细数据,不能取消数量核检!!!");
            }

            item.setAoaQty("N");
        }

        return ResponseInfo.ok(pcPayMapper.updateAoaQty(records));
    }

    @Override
    public void downloadAoa(HttpServletResponse response, FinancePayable financePayable) throws IOException {
        financePayable.setCompanyId(UserIdThread.get().getCompanyId());
        List<FinancePayable> list = pcPayMapper.payableAoaList(financePayable);
        extracted1(list);
        ExcelUtils.creatByTemplate(response, "finance_payable_aoa.xls", "AOA-payable-" + DateUtils.dateTimeNow(), list);
    }

    @Override
    public void downloadPayable(HttpServletResponse response, FinancePayable financePayable) throws IOException {
        financePayable.setCompanyId(UserIdThread.get().getCompanyId());
        List<FinancePayable> list = pcPayMapper.payableList(financePayable);
        extracted1(list);
         ExcelUtils.creatByTemplate(response, "finance_payable.xls", "payable-" + DateUtils.dateTimeNow(), list);
    }

    private static void extracted1(List<FinancePayable> list) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat format1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        for (FinancePayable payable : list) {
            String aoaCfm = payable.getAoaCfm() == null ? "" : payable.getAoaCfm();
            String exportFlag = payable.getExportFlag() == null ? "N" : payable.getExportFlag();
            payable.setAoaCfm("Y".equals(aoaCfm) ? "是" : "否");
            payable.setExportFlag("Y".equals(exportFlag) ? "是" : "否");
            if (payable.getAoaDate() != null) payable.setAoaTime(format.format(payable.getAoaDate()));
            if (payable.getSysDate() != null) payable.setSysTime(format1.format(payable.getSysDate()));
            if (payable.getShipDate() != null) payable.setShipTime(format.format(payable.getShipDate()));
            if (payable.getOutDate() != null) payable.setOutTime(format.format(payable.getOutDate()));
        }
    }


    private void extracted(List<FinanceReceivable> req) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMM");
        String date = sdf.format(new Date());
        String key = "S" + date;
        RedisAtomicInteger ato = new RedisAtomicInteger(key, redisService.getConnectionFactory());
        int maxReceiptNo = ato.incrementAndGet();
        Iterator var4 = req.iterator();
        while (var4.hasNext()) {
            FinanceReceivable item = (FinanceReceivable) var4.next();
            BigDecimal amt = pcPayMapper.getAmtByReceiptNo(item);
            amt = amt == null ? new BigDecimal("0") : amt;
            amt = amt.add(new BigDecimal(item.getRecAmt()));
            if (amt.doubleValue() > (item.getArAmt())) throw new ServiceErrorException("收款金额小于应收金额！！！");
            item.setReceiptNo(key + String.format("%04d", maxReceiptNo));
            item.setSysUser(UserIdThread.get().getLoginName());
            item.setSysDate(new Date());
        }
    }
}